
import sys
import time
import logging

import style

import plumbum
import plumbum.cli    as cli
import plumbum.cmd    as cmd
import plumbum.colors as colors
import plumbum.commands
import plumbum.lib
import plumbum.machines

from plumbum import TEE, FG, BG
from plumbum.machines.session import ShellSession

import plumvgr


def log(*args):
	lines = ' '.join(map(str, args)).splitlines(keepends=True)
	text  = '    '.join(lines)
	print(style.light_white('$$$'), style.white(text))


def blue(*args):
	blue.counter += 1
	lines = ' '.join(map(str, args)).splitlines(keepends=True)
	text  = '    '.join(lines)
	print(style.light_cyan('-{}-'.format(blue.counter)), style.cyan(text))
blue.counter = 0


class Foo(cli.Application):
	debug = cli.Flag('--debug')

#	def show_colors(self):
#		with colors.red:
#			print("This library provides safe, flexible color access.")
#			print(colors.bold | "(and styles in general)", "are easy!")
#		print("The simple 16 colors or",
#			colors.orchid & colors.underline | '256 named colors,',
#			colors.rgb(18, 146, 64) | "or full rgb colors",
#			'can be used.')
#		print("Unsafe " + colors.bg.dark_khaki + "color access" + colors.bg.reset + " is available too.")

	def setupLogger(self):
		try:
			import colorlog
		except ImportError:
			logging.basicConfig(
				level=logging.DEBUG if self.debug else logging.WARNING,
#				format='[%(levelname)s] {%(name)s} %(message)s')
				format ='%(asctime)s.%(msecs)03d {%(name)s} %(message)s',
				datefmt='%H:%M:%S')
		else:
			logger = logging.getLogger()

			if not logger.handlers:
				handler = logging.StreamHandler()
				handler.setFormatter(colorlog.ColoredFormatter(
#					'%(log_color)s[%(levelname)s]%(reset)s '\
#					'%(white)s{%(name)s}%(reset)s '\
#					'%(message_log_color)s%(message)s',
					'%(reset)s%(asctime)s.%(msecs)03d '\
					'%(white)s{%(name)s}%(reset)s '\
					'%(log_color)s%(message)s',
					datefmt   ='%H:%M:%S',
					log_colors={
						'DEBUG'   : 'cyan',
						'INFO'    : 'green',
						'WARNING' : 'yellow',
						'ERROR'   : 'red',
						'CRITICAL': 'red,bg_white'},
					secondary_log_colors={'message': {
						'WARNING' : 'yellow',
						'ERROR'   : 'red',
						'CRITICAL': 'red'}},
				))
				logger.addHandler(handler)
				logger.setLevel(logging.DEBUG if self.debug else logging.WARNING)

	def main(self):
		self.setupLogger()

		with plumvgr.VagrantMachine() as vag:
			response = vag.getSession().run('echo stdout')
			assert response == (0, 'stdout\n', ''), response
			response = vag.getSession().run('echo stderr >&2')
			assert response == (0, '', 'stderr\n'), response

			vag.env['XXX'] = 'yyy'

			env = vag['env']().strip()
			log(env)
			assert 'XXX=yyy' in env

			log(vag['ls']['/'] & TEE)

			# Pipe породит ещё одну сессию (vagrant ssh) и её смерть (для sort) из-за необходимости `stdin.close`
			(vag['ls']['/'] | vag['sort']['-r']) & FG
			log(vag['sh']['-c', 'id; pwd']().strip())  # (в оригинале) вызывает `popen`, а это (очень) медленно

			future = vag['sh']['-c', 'sleep 3; pwd; cd /etc; pwd'] & BG
			print(style.yellow('-1-', future))

			with vag.cwd('/') as cwd:
				time.sleep(0.2)
				blue('cwd:', repr(cwd))

				#
				env = vag['env']().strip()
				log(env)
				assert 'XXX=yyy' in env

				future.wait()  # @xxx: после этого, `env` может измениться

				pwd = vag['pwd']().strip()
				log(pwd)
				assert pwd == '/', (pwd, cwd)

			out2 = future.stdout.strip().replace('\n', '; ')
			print(style.yellow('-2-', future.returncode, '"{}"'.format(out2)))
			assert out2 == '/home/vagrant; /etc'

			log(vag['uname']['-a']().strip())
			log(vag.cmd.pwd().strip())

			del vag.env['XXX']

			env = vag['env']().strip()
			log(env)
			assert 'XXX=yyy' not in env
